#ifndef __CRYGAMESPYFRIENDSMANAGEMENT_H__
#define __CRYGAMESPYFRIENDSMANAGEMENT_H__

#if _MSC_VER > 1000
#pragma once
#endif

#include "CryGameSpyLobby.h"

#if USE_CRYLOBBY_GAMESPY

#include "Lobby/CryFriendsManagement.h"

struct SCryGameSpyUserID;

class CCryGameSpyFriendsManagement : public CCryFriendsManagement, ICryGameSpyLobbyComponent
{
public:
															CCryGameSpyFriendsManagement(CCryLobby* pLobby, CCryLobbyService* pService);

					void								Tick(CTimeValue tv);

					// ICryFriendsManagment
	virtual ECryLobbyError			FriendsManagementSendFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementAcceptFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementRejectFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementRevokeFriendStatus(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementIsUserFriend(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementInfoCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementFindUser(uint32 user, SFriendManagementSearchInfo* pUserName, uint32 maxResults, CryLobbyTaskID* pTaskID, CryFriendsManagementSearchCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementBlockUser(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementUnblockUser(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementIsUserBlocked(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementInfoCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementAcceptInvite(uint32 user, CryUserID* pUserID, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementGetName(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementSearchCallback pCb, void* pCbArg);
	virtual ECryLobbyError			FriendsManagementGetStatus(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementStatusCallback pCb, void* pCbArg);
					// ~ICryFriendsManagment

					// ICryGameSpyLobbyComponent
	virtual void OnGameSpyObjectAvailable(EGameSpyObjectBit object);
	virtual void OnGameSpyObjectUnavailable(EGameSpyObjectBit object);
	virtual void OnGameSpyObjectCantMakeAvailable( EGameSpyObjectBit object );
					// ~ICryGameSpyLobbyComponent

					void								LateInitialise(GPConnection* pGPConnection, GPProfile gpProfile, _smart_ptr<CCryGameSpyFriends> pFriends);

protected:

	virtual void								FreeTask(CryFriendsManagementTaskID fTaskID);

private:
	enum ETask
	{
		eT_FriendsManagementSendFriendRequest,
		eT_FriendsManagementAcceptFriendRequest,
		eT_FriendsManagementRejectFriendRequest,
		eT_FriendsManagementRevokeFriendStatus,
		eT_FriendsManagementIsUserFriend,
		eT_FriendsManagementFindUser,
		eT_FriendsManagementBlockUser,
		eT_FriendsManagementUnblockUser,
		eT_FriendsManagementIsUserBlocked,
		eT_FriendsManagementAcceptInvite,
		eT_FriendsManagementGetStatus
	};

	struct  STask : public CCryFriendsManagement::STask
	{
		CTimeValue								m_timeStarted;
		bool											m_haveGPConnection;
		bool											m_taskStarted;
	};

					ECryLobbyError			InitialiseTask(ETask taskType, uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, void* pCb, void* pCbArg);

					ECryLobbyError			StartTask(ETask etask, bool startRunning, uint32 user, CryFriendsManagementTaskID* pFTaskID, CryLobbyTaskID* pLTaskID, CrySessionHandle h, void* pCb, void* pCbArg);
					void								StartTaskRunning(CryFriendsManagementTaskID fTaskID);
					void								EndTask(CryFriendsManagementTaskID fTaskID);
					void								StopTaskRunning(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID);

					void								StartFriendsManagementGetStatus(CryFriendsManagementTaskID fTaskID);
					void								TickFriendsManagementGetStatus(CryFriendsManagementTaskID fTaskID);
					void								EndFriendsManagementGetStatus(CryFriendsManagementTaskID fTaskID);

					CryFriendsManagementTaskID	GetTaskID(GPConnection* pGPConnection, GPProfile gpProfile);
					CCryGameSpyLobbyService*	GetService() { return (CCryGameSpyLobbyService*)m_pService; }

					void								EndFriendsManagementTaskWithInfo(CryFriendsManagementTaskID fTaskID);

	static	void								FindUserCallback(GPConnection* pGPConnection, void* pArg, void* pParam);

	STask												m_task[MAX_FRIENDS_MANAGEMENT_TASKS];
	_smart_ptr<CCryGameSpyFriends>	m_pFriends;
	GPConnection*								m_pGPConnection;
	GPProfile										m_GPProfile;
};

#endif // USE_CRYLOBBY_GAMESPY
#endif // __CRYGAMESPYFRIENDSMANAGEMENT_H__